<template>
    <div class="custom-view">
        <component v-bind:is="currentView" ref="component" :config="config" :params="params"  @customViewEvent="customViewEvent"
                   @jumpMenuByKey="jumpMenuByKey"
                   :customQueryData="customQueryData"></component>
    </div>
</template>

<script>
import Vue from 'vue';
import FormCustomQueryApi from "@/api/form/core/formCustomQuery";
import {debounce} from "lodash-es";
import PublicApi from "@/api/form/core/public";
import BusEvent from "@/views/modules/form/core/formComponent/BusEvent";
import rxAjax from '@/assets/js/ajax.js';
import {PublicFunction,CustomViewFunc,Util} from "@lowcode/jpaas-common-lib";
import ShareFunction from "@/assets/js/ShareFunction";
import {mapState} from "vuex";

export default {
    name: "custom-view",
    mixins:[BusEvent],
    props: {
        config:{
            type:Object,
            default:{}
        },
        layoutItem:{
            type:Object,
            default:{}
        }
    },
    components: {
    },
    data() {
        return {
            currentView:"",
            customQueryData:[],
            defScript:"export default {\n" +
                "    props: {\n" +
                "        //" + this.i18n2('queryData', '自定义查询数据') + "\n" +
                "        customQueryData: {type: Array,default:[]},\n" +
                "        //" + this.i18n2('config', '配置') + "\n" +
                "        config: {type: Object,default:{}},\n" +
                "        //" + this.i18n2('param', '参数') + "\n" +
                "        params: {type: Object,default:{}},\n" +
                "    },\n" +
                "   //" + this.i18n2('defaultJsDesc1', '数据定义') + "\n" +
                "    data(){\n" +
                "        return {\n" +
                "        }\n" +
                "    },\n" +
                "    //" + this.i18n2('defaultJsDesc2', '初始化时加载') + "\n" +
                "    created(){},\n" +
                "    //" + this.i18n2('defaultJsDesc3', '页面自定义函数') + "\n" +
                "    methods:{\n" +
                "        /**\n" +
                "         * @param data {key:value}\n" +
                "         */\n" +
                "        customViewEvent(data){\n" +
                "            this.$emit('customViewEvent',{component:this.config.alias,params:data});\n" +
                "        }\n" +
                "    },\n" +
                "    //" + this.i18n2('defaultJsDesc5', '页面自定义观察函数') + "\n" +
                "    watch:{}\n" +
                "}",
            params:{}
        }
    },
    computed: {
        ...mapState({
            menus: state => state.appSetting.menus
        })
    },
    created() {
        this.init();
    },
    methods: {
        i18n2(name, text, key) {
            return this.$ti18(name, text, "scriptInsertLang", key);
        },
        init(){
            var self=this;
            if(this.config){
                //自定义查询
                var params={};
                if(this.config.customSql){
                    var alias = JSON.parse(this.config.customSql).value;
                    var parameter={};
                    if (this.config.receive.type == 'url') {
                        //取路由参数
                        var routeParams=this.getRouterParams();
                        var mapping = this.config.receive.mapping;
                        if(mapping && mapping.length>0 ){
                            for (var i = 0; i < mapping.length; i++) {
                                var value="";
                                if(mapping[i].valueSource=='param'){
                                    if(this.config.receive.type== "url"){
                                        if(routeParams[mapping[i].valueDef]){
                                            value=routeParams[mapping[i].valueDef];
                                        }
                                    }else {
                                        if( routeParams[mapping[i].name]){
                                            value=routeParams[mapping[i].name];
                                        }
                                    }
                                }
                                params[mapping[i].name]=value;
                            }
                        }
                    }
                    this.params=params;
                    this.getParams(function (res) {
                        if(res){
                            Object.assign(params,res);
                        }
                        if(params){
                            parameter.params=JSON.stringify(params);
                        }
                        self.getCustomQueryData(alias,parameter);
                    })
                }
                //vue文件
                if(self.config.mode=="file"){
                    if(self.config.path){
                        self.currentView=self.loadView(self.config.path);
                    }
                }else {
                    //加载js
                    var jsScript="";
                    var script_="";
                    if(this.config.jsScript){
                        jsScript=this.config.jsScript;
                    }else {
                        //设置默认js
                        jsScript=this.defScript;
                    }
                    jsScript=Util.replaceDefault(jsScript);
                    script_=eval('('+jsScript+')');
                    if(this.config.template) {
                        this.currentView = Vue.component("component-view"+this.config.alias, {
                            template: this.config.template,
                            components:{
                                rxAjax
                            },
                            mixins:[PublicFunction,ShareFunction,CustomViewFunc],
                            ...script_
                        });
                        this.loadStyle();
                    }
                }
            }
        },
        loadView(view){ // 路由懒加载
            return () => import(`@/views/${view}`)
        },
        //获取自定义查询数据
        getCustomQueryData(alias,parameter){
            FormCustomQueryApi.doQuery(alias,parameter).then(res=>{
                if(res.success && res.data){
                    this.customQueryData=res.data;
                }
            });
        },
        handReceive :debounce(function (args, self_){
            var receive=self_.config.receive;
            var inputParams=args.params;
            if(self_.config.receive.type=='event' && receive.publishComponent==args.component){
                var params={};
                //自定义查询
                if(self_.config.customSql){
                    var alias = JSON.parse(self_.config.customSql).value;
                    //读取配置的参数
                    for(var i=0;i<receive.mapping.length;i++){
                        var o=receive.mapping[i];
                        //处理没有配置值来源的情况。
                        if(!o.valueDef && inputParams[o.name]){
                            params[o.name]=inputParams[o.name]
                        }
                        else if(o.valueSource=='param' && inputParams[o.valueDef]){
                            params[o.name]=inputParams[o.valueDef];
                        }
                    }
                    self_.params=params;
                    self_.getCustomQueryData(alias,{params:JSON.stringify(params)});
                }
            }
        },300),
        //发布事件
        customViewEvent(data){
            this.$bus.$emit('customViewEvent',data);
        },
        getParams(callback){
            PublicApi.getParams(JSON.stringify(this.config.receive.mapping)).then(res=>{
                callback(res);
            }).catch(err=>{
                callback({});
            })
        },
        //加载css
        loadStyle(){
            var cssStyle="<style scoped>" + this.config.cssStyle + "</style>"
            var style="";
            var styleMath = cssStyle.match(/<style scoped>([\s\S]*)<\/style>/) || cssStyle.match(/<style>([\s\S]*)<\/style>/);
            if (styleMath != null) {
                style=styleMath[1];
            }
            var newStyle=document.getElementById("customStyle"+this.config.alias);
            if(!newStyle){
                newStyle = document.createElement('style');
                document.getElementsByTagName('head')[0].appendChild(newStyle)
            }
            newStyle.id="customStyle"+this.config.alias;
            newStyle.innerHTML = style;
        },
        /**
         * 跳转菜单
         * @param key
         */
        jumpMenuByKey(key,params){
            let menu=this.getMenuByKey(key,this.menus);
            let newMenu=JSON.parse(JSON.stringify(menu))
            let menuParams=JSON.parse(newMenu.params);
            menuParams=Object.assign(menuParams,params);
            newMenu.params=JSON.stringify(menuParams);
            this.$bus.emit('handMenuClick', newMenu);
        },
        //根据获取菜单
        getMenuByKey(key,menus){
            let menu;
            for (let i = 0; i <menus.length ; i++) {
                if(menus[i].key==key){
                    menu=menus[i];
                    break;
                }else {
                    if(menus[i].children&&menus[i].children){
                        menu=this.getMenuByKey(key,menus[i].children);
                        if(menu) break;
                    }
                }
            }
            return menu;
        },
        handPublicReceive(args){
            //执行 自定义的方法。
            let method= args.method;
            if(args.method){
                let vm=this.$refs.component;
                let vmMethod=vm[method];
                if(!vmMethod){
                    this.$message.warn("请在当前组件中配置方法:" +method)
                    return;
                }
                let data=args.data;
                if(data){
                    vmMethod(data);
                }
                else{
                    vmMethod();
                }
                return;
            }

            var receive = this.config.receive;
            var inputParams=args.params;
            var params={};
            if(receive.mapping && receive.mapping.length>0){
                //读取配置的参数
                for(var i=0;i<receive.mapping.length;i++){
                    var o=receive.mapping[i];
                    //处理没有配置值来源的情况。
                    params[o.name]=inputParams[o.name]
                }
            }
            this.params=Object.assign(inputParams,params);
            //自定义查询
            if(this.config.customSql){
                var alias = JSON.parse(this.config.customSql).value;
                this.getCustomQueryData(alias,{params:JSON.stringify(this.params)});
            }
        },
    },
    watch: {
        config:{
            handler: function (val, oldVal) {
                this.init();
            },
            deep: true
        }
    }
}
</script>

<style scoped>
.custom-view{
    padding: 10px;
    background: white;
    height: 100%;
    overflow: auto;
}
</style>